package com.qingyun.web.security.filter;

import com.alibaba.fastjson.JSON;


import com.qingyun.common.utils.StringUtils;
import com.qingyun.security.config.TenantContextHolder;
import com.qingyun.security.enums.LoginRole;
import com.qingyun.security.enums.LoginType;
import com.qingyun.security.exception.AuthoException;
import com.qingyun.security.model.shop.AppMiniAppBody;
import com.qingyun.security.token.MyAuthenticationToken;
import com.qingyun.web.security.token.WxMiniAppAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author dangyonghang
 */
public class MiniAppLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private static String loginUrl="/miniapp/login";

    private AuthenticationManager authenticationManager;

    public MiniAppLoginAuthenticationFilter()
    {
        super(new AntPathRequestMatcher(loginUrl, "POST"));
    }

    @Override
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        super.setAuthenticationManager(authenticationManager);
        this.authenticationManager=authenticationManager;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
        String stringFromStream = getStringFromStream(httpServletRequest);
		AppMiniAppBody miniAppBody = JSON.parseObject(stringFromStream, AppMiniAppBody.class);
		if (StringUtils.isBlank(miniAppBody.getWxcode())) {
			throw new AuthoException("微信code不能为空");
		}
		LoginType loginType = LoginType.selectLoginType(miniAppBody.getLoginType());
		Authentication authenticate=null;
        try{

			MyAuthenticationToken authenticationToken=null;
			if (miniAppBody.getPhone()!=null) {
				miniAppBody.setUserName(miniAppBody.getPhone());
			}
			String credentials=null;
			switch (loginType){
				case PASSWORD:
               credentials=miniAppBody.getPassWord();
					break;
				case PHONE:
				credentials=miniAppBody.getCode();
					break;
				default:
					throw new AuthoException("不支持此类型登陆");
			}
			authenticationToken = new WxMiniAppAuthenticationToken(miniAppBody.getUserName(),credentials,miniAppBody.getWxcode(),loginType);
			TenantContextHolder.setTenantType(LoginRole.WXMALOGIN);

			authenticate = authenticationManager.authenticate(authenticationToken) ;
         } catch (Exception e) {
            throw new AuthoException(e.getMessage());
         } finally {
          TenantContextHolder.clearTenantType();
         }
        return authenticate;
    }

    private String getStringFromStream(HttpServletRequest req) {
        ServletInputStream is;
        try {
            is = req.getInputStream();
            int nRead = 1;
            int nTotalRead = 0;
            byte[] bytes = new byte[10240];
            while (nRead > 0) {
                nRead = is.read(bytes, nTotalRead, bytes.length - nTotalRead);
                if (nRead > 0) {
                    nTotalRead = nTotalRead + nRead;
                }
            }
            return new String(bytes, 0, nTotalRead, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}
